package net.teamclerks.rpgf.character.statsheet;

import java.util.HashMap;
import java.util.Map;

import net.teamclerks.rpgf.character.Character;
import net.teamclerks.rpgf.character.stats.StatSheet;
import net.teamclerks.rpgf.inventory.item.equipment.ArmorItem;
import net.teamclerks.rpgf.inventory.item.equipment.WeaponItem;
import net.teamclerks.rpgf.script.director.Director;

/**
 * CharacterEquipmentStatSheet is the culmination of all EquipmentStatSheets
 * for every EquipmentItem equipped for a given Character. The purpose of
 * splitting this implementation up is to make a distinction between a
 * Character's base stats, the stats from all his equipped items, and the
 * stats on a single EquipmentItem.
 * 
 * @author kain
 *
 */
public class CharacterEquipmentStatSheet extends StatSheet
{
  /// DATA POINTS ///
  protected Map<Integer, ArmorItem> equipment;
  protected Map<Integer, WeaponItem> weapons;
  protected Character owner;
  
  /// PUBLIC CONSTRUCTOR ///
  public CharacterEquipmentStatSheet(Director director, Character owner)
  {
    super(director);
    this.owner = owner;
    this.owner.setEquipmentStatSheet(this);
    this.equipment = new HashMap<Integer, ArmorItem>();
    this.weapons = new HashMap<Integer, WeaponItem>();
  }
  
  /// PUBLIC FINAL METHODS ///
  public final Map<Integer, WeaponItem> getWeapons()
  {
    return this.weapons;
  }
  public final Map<Integer, ArmorItem> getArmor()
  {
    return this.equipment;
  }
  public final Character getOwner()
  {
    return this.owner;
  }
  public final void setOwner(Character owner)
  {
    this.owner = owner;
  }
  /**
   * Gets the ArmorItem for a given slot.
   * @param slot
   */
  public final ArmorItem getArmorInSlot(int slot)
  {
    return this.equipment.get(slot);
  }
  /**
   * Gets the EquipmentItem for a given slot.
   * @param slot
   */
  public final WeaponItem getWeaponInSlot(int slot)
  {
    return this.weapons.get(slot);
  }
  /**
   * Equips an ArmorItem. Returns the ArmorItem previously in the same
   * slot (if one was present, null if it was empty).
   * @param item
   * @return unequipped
   */
  public final ArmorItem equipArmor(ArmorItem item)
  {
    ArmorItem unequipped = this.unequipArmor(item.getSlot());
    
    this.equipment.put(item.getSlot(), item);
    this.applyStats(item.getEquipmentStatSheet());
    
    return unequipped;
  }
  /**
   * Attempts to unequip an ArmorItem.
   * @param slot
   * @return unequipped
   */
  public final ArmorItem unequipArmor(int slot)
  {
    ArmorItem unequipped = this.equipment.remove(slot);
    if(unequipped != null)
    {
      removeStats(unequipped.getEquipmentStatSheet());
    }
    return unequipped;
  }
  /**
   * Equips a WeaponItem. Returns the WeaponItem previously in the same
   * slot (if one was present, null if it was empty).
   * @param item
   * @return unequipped
   */
  public final WeaponItem equipWeapon(WeaponItem item)
  {
    WeaponItem unequipped = this.unequipWeapon(item.getSlot());

    this.weapons.put(item.getSlot(), item);
    this.applyStats(item.getEquipmentStatSheet());
    
    return unequipped;
  }
  /**
   * Attempts to unequip a WeaponItem.
   * @param slot
   * @return
   */
  public final WeaponItem unequipWeapon(int slot)
  {
    WeaponItem unequipped = this.weapons.remove(slot);
    if(unequipped != null)
    {
      removeStats(unequipped.getEquipmentStatSheet());
    }
    return unequipped;
  }
}
